/**
 * 绘图类
 * @author zzhanglin
 * @returns {Graphics}
 */
Graphics  = function()
{
	this.className = "Graphics";
	this._enable= false ;
	//临时的context
	this._context ;
};

Graphics.prototype._getContext = function()
{
	if(this._context) return this._context ;
	//如果没有创建的话，先创建
	var canvas = document.createElement("canvas");
	canvas.width = 1;
	canvas.height = 1 ;
	this._context = canvas.getContext("2d");
	canvas = null ;
	//初始化
	Graphics._init(this, this._context );
	return this._context ;
};

/**
 * @private
 */
Graphics.prototype._proxy = function(context, func, alias)
{	
	this[func] = function()
	{
		var obj = context[func].apply(context, arguments) ;
		if(obj) return obj ;
		else return this;
	};
	if(alias) this[alias] = this[func];
};

/**
 * @private
 */
Graphics._init = function(g, context)
{	
	g._proxy(context, "beginPath");
	g._proxy(context, "closePath");
	g._proxy(context, "stroke");
	g._proxy(context, "fill");
	g._proxy(context, "moveTo");
	g._proxy(context, "lineTo");
	
	g._proxy(context, "arcTo");
	g._proxy(context, "arc");
	g._proxy(context, "quadraticCurveTo", "curveTo");
	g._proxy(context, "bezierCurveTo");
	g._proxy(context, "rect");
	
	g._proxy(context, "createLinearGradient");
	g._proxy(context, "createRadialGradient");
	g._proxy(context, "createPattern");	
	
	g.fillStyle = null;
	g.strokeStyle = null;	
	g.fillAlpha = 1;
	g.lineAlpha = 1;
	g.lineWidth = 1;
};

Graphics.prototype.lineStyle = function(thickness, lineColor, alpha, lineCap, lineJoin, miterLimit)
{
	this.lineWidth = this._getContext().lineWidth = thickness || 1;
	this.strokeStyle = this._getContext().strokeStyle = lineColor || "0";
	this.lineAlpha = alpha || 1;
	if(lineCap != undefined) this._getContext().lineCap = lineCap;
	if(lineJoin != undefined) this._getContext().lineJoin = lineJoin;
	if(miterLimit != undefined) this._getContext().miterLimit = miterLimit;
	return this;
};

Graphics.prototype.beginLinearGradientFill = function(x0, y0, x1, y1, colors, ratios)
{
	var gradient = this.createLinearGradient(x0, y0, x1, y1);
	for (var i = 0, len = colors.length; i < len; i++)
	{
		gradient.addColorStop(ratios[i], colors[i]);
	}
	this.fillStyle = gradient;
	return this;
};

Graphics.prototype.beginRadialGradientFill = function(x0, y0, r0, x1, y1, r1, colors, ratios)
{
	var gradient = this.createRadialGradient(x0, y0, r0, x1, y1, r1);
	for (var i = 0, len = colors.length; i < len; i++)
	{
		gradient.addColorStop(ratios[i], colors[i]);
	}
	this.fillStyle = gradient;
	return this;
};

Graphics.prototype.beginBitmapFill = function(image, repetition)
{
	repetition = repetition || "";
	this.fillStyle = this.createPattern(image, repetition);
	return this;
};

/**
 * 填充颜色
 * @param color 填充颜色，字符串，如"#cccccc"
 * @alpha 透明度
 */
Graphics.prototype.beginFill = function(color, alpha)
{
	if(color) 
	{
		this._getContext().fillStyle = color;
		this.fillStyle = color ;
	}
	this.fillAlpha = alpha || 1;
	return this;
};

Graphics.prototype.endFill = function()
{
	if(this.strokeStyle) 
	{
		this._getContext().strokeStyle = this.strokeStyle;
		this._getContext().globalAlpha = this.lineAlpha;
		this._getContext().stroke();
	}
	if(this.fillStyle) 
	{
		this._getContext().fillStyle = this.fillStyle;
		this._getContext().globalAlpha = this.fillAlpha;
		this._getContext().fill();
	}
	this._enable= true ;
	return this;
};

Graphics.prototype.drawRect = function(x, y, width, height)
{
	this.setSize(width,height);
	this.beginPath();
	this.rect(x, y, width, height);
	this.closePath();
	this.endFill();
	return this;
};

Graphics.prototype.drawRoundRect = function(x, y, width, height, cornerSize)
{
	this.setSize(width,height);
	return this.drawRoundRectComplex(x, y, width, height, cornerSize, cornerSize, cornerSize, cornerSize);
};

Graphics.prototype.drawRoundRectComplex = function(x, y, width, height, cornerTL, cornerTR, cornerBR, cornerBL)
{
	this.setSize(width,height);
	this.beginPath();
	this.moveTo(x + cornerTL, y);
	this.lineTo(x + width - cornerTR, y);
	this.arc(x + width - cornerTR, y + cornerTR, cornerTR, -Math.PI/2, 0, false);
	this.lineTo(x + width, y + height - cornerBR);
	this.arc(x + width - cornerBR, y + height - cornerBR, cornerBR, 0, Math.PI/2, false);
	this.lineTo(x + cornerBL, y + height);
	this.arc(x + cornerBL, y + height - cornerBL, cornerBL, Math.PI/2, Math.PI, false);
	this.lineTo(x, y + cornerTL);
	this.arc(x + cornerTL, y + cornerTL, cornerTL, Math.PI, Math.PI*3/2, false);
	this.closePath();
	this.endFill();
	return this;
};

Graphics.prototype.drawCircle = function(x, y, radius)
{
	this.setSize(radius*2,radius*2);
	this.beginPath();
	this.arc(x + radius, y + radius, radius, 0, Math.PI * 2, 0);
	this.closePath();
	this.endFill();
	return this;
};

Graphics.prototype.drawEllipse = function(x, y, width, height)
{
	if(width == height) return this.drawCircle(x, y, width);
	var w = width / 2;
	var h = height / 2;
	var C = 0.5522847498307933;
	var cx = C * w;
	var cy = C * h;
	x = x + w;
	y = y + h;
	this.setSize(w,h);
	this.beginPath();
	this.moveTo(x + w, y);
	this.bezierCurveTo(x + w, y - cy, x + cx, y - h, x, y - h);
	this.bezierCurveTo(x - cx, y - h, x - w, y - cy, x - w, y);
	this.bezierCurveTo(x - w, y + cy, x - cx, y + h, x, y + h);
	this.bezierCurveTo(x + cx, y + h, x + w, y + cy, x + w, y);
	this.closePath();
	this.endFill();
	return this;
};

Graphics.prototype._getContextCanvas = function()
{
	return this._getContext().canvas;
};

Graphics.prototype.setSize = function(width, height)
{	
	if(width != undefined) this._getContext().canvas.width = width;
	if(height != undefined) this._getContext().canvas.height = height;
	return this;
};

Graphics.prototype.clear = function()
{
	this._getContext().clearRect(0, 0, this._getContext().canvas.width, this._getContext().canvas.height);
	this._getContext().restore();
	this._enable= false ;
	return this;
};

Graphics.prototype._dispose = function()
{
	if(this._context){
		this._getContext().width = 1;
		this._context = null ;
	}
};